import json
import datetime
import threading
import queue                                                
import time
import asyncio                                               # 导入asyncio支持异步操作
import os                                                    # 导入os模块用于文件操作
import sys                                                   # 导入sys模块

# 将项目根目录添加到Python路径
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

from concurrent.futures import ThreadPoolExecutor         # 导入ThreadPoolExecutor
# 从LLM_Client导入新的API函数
from core.LLM_Client import call_deepseek_Tool_api              # 导入call_deepseek_Tool_api
from wechat.SUD_UserProfile_Update import save_messages_to_file  # 导入save_messages_to_file函数
from wechat.SUD_NewMessage_Received import check_messages        # 导入check_messages函数
from wechat.SUD_GetMessage import _init_wechat                   # 导入_init_wechat函数
from core.logger import get_logger                             # 导入日志模块
# 导入配置管理器
from config.config_manager import get_api_key

# 创建模块特定的日志记录器
logger = get_logger("main")

# 全局任务队列
ai_task_queue = queue.Queue()
# 全局结果字典
ai_results = {}
# 线程池
executor = ThreadPoolExecutor(max_workers=5)
# 线程锁
lock = threading.Lock()


def build_deepseek_messages(saved_file_path, prompt_file='resources/Main_prompt.txt'):
    """
    构建用于DeepSeek API的消息列表
    
    Args:
        saved_file_path (str): 保存消息的文件路径
        prompt_file (str): 系统提示文件路径，默认为'Main_prompt.txt'
        
    Returns:
        list: 构建好的messages列表
    """
    logger.info(f"开始构建DeepSeek消息，文件路径: {saved_file_path}")
    
    try:
        # 从保存的文件中读取消息
        with open(saved_file_path, 'r', encoding='utf-8') as f:
            messages = json.load(f)
        
        logger.info(f"已从 {saved_file_path} 读取 {len(messages)} 条消息")
        
        # 读取系统提示文件内容
        with open(prompt_file, 'r', encoding='utf-8') as f:
            prompt_content = f.read()
        
        # 创建system消息并插入到messages列表的开头
        messages.insert(0, {"role": "system", "content": prompt_content})
        
        logger.info("已将系统提示添加到消息列表的开头")
        
        return messages
    except Exception as e:
        logger.error(f"构建DeepSeek消息时出错: {str(e)}")
        raise

def ai_worker():
    """
    后台线程，处理AI任务队列中的任务
    """
    logger.info("AI工作线程启动")
    
    while True:
        try:
            # 从队列获取任务
            task_id, friend_name, messages, api_key = ai_task_queue.get(timeout=1)
            logger.info(f"处理任务 {task_id}，好友：{friend_name}")
            
            # 调用异步API并等待结果
            logger.debug(f"调用DeepSeek API，消息数量: {len(messages)}")
            api_result = asyncio.run(call_deepseek_Tool_api(api_key, messages))
            
            # 从返回结果中提取final_response
            result = api_result["final_response"]
            
            # 获取当前时间
            current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            
            # 构造数据
            data = {
                "Status": "未使用",
                "friend_name": friend_name,
                "messages": api_result["messages"],  
                "reasoning_content": result.get("reasoning_content", "无推理内容"),
                "content": result.get("content", "无回复内容"),
                "time": current_time
            }
            
            # 保存结果
            with lock:                              # 线程锁
                save_task_to_config(data)           # 保存结果到配置文件
                ai_results[task_id] = data          # 保存结果到全局字典
            
            logger.info(f"任务 {task_id} 处理完成")
            ai_task_queue.task_done()               # 通知队列任务完成

        except queue.Empty:
            # 队列为空，短暂休眠
            time.sleep(0.1)
            
        except Exception as e:
            logger.error(f"AI处理任务出错: {str(e)}", exc_info=True)
            ai_task_queue.task_done()               # 通知队列任务完成

def save_task_to_config(data):
    """
    保存任务数据到配置文件
    
    Args:
        data: 要保存的任务数据
    """
    config_file = "config/push_task_config.json"
    logger.info(f"开始保存任务数据到 {config_file}")
    
    # 检查文件是否存在，如果存在则读取现有数据
    try:
        with open(config_file, 'r', encoding='utf-8') as f:
            existing_data = json.load(f)
            # 如果现有数据不是列表，则创建一个包含现有数据的列表
            if not isinstance(existing_data, list):
                logger.debug("配置文件格式不是列表，转换为列表")
                tasks = [existing_data]
            else:
                tasks = existing_data
    except (FileNotFoundError, json.JSONDecodeError):
        # 文件不存在或为空，创建新的列表
        logger.debug(f"配置文件 {config_file} 不存在或格式错误，创建新列表")
        tasks = []
    
    # 将新数据追加到列表中
    tasks.append(data)
    
    # 将更新后的列表写回文件
    try:
        with open(config_file, 'w', encoding='utf-8') as f:
            json.dump(tasks, f, ensure_ascii=False, indent=4)
        
        logger.info(f"已将推送任务数据追加至 {config_file}，当前共有 {len(tasks)} 条任务")
    except Exception as e:
        logger.error(f"保存任务数据到配置文件时出错: {str(e)}")


def handle_ai_chat(friend_name, messages, api_key):
    """
    处理AI聊天请求（异步版本）
    
    Args:
        friend_name: 好友名称
        messages: 消息列表
        api_key: API密钥
        
    Returns:
        str: 任务ID
    """
    # 生成任务ID
    task_id = f"{friend_name}_{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}"
    
    logger.info(f"创建AI聊天任务 {task_id} 用于好友 {friend_name}")
    
    # 将任务添加到队列
    ai_task_queue.put((task_id, friend_name, messages, api_key))
    
    logger.info(f"已将好友 {friend_name} 的聊天任务添加到队列，任务ID: {task_id}")
    
    return task_id

def publish_messages():
    """
    读取push_task_config.json文件中Status为"未使用"的数据，
    获取friend_name和content字段，调用wx.SendMsg进行发布，
    并将已发布的消息Status更新为"已使用"
    
    Returns:
        int: 成功发布的消息数量
    """
    logger.debug("开始发布消息流程")
    
    # 初始化微信实例
    wx = _init_wechat()

    # 读取配置文件
    config_file = "config/push_task_config.json"

    # 初始化发布计数
    published_count = 0
    
    try:
        # 检查文件是否存在，不存在则创建空的任务列表文件
        if not os.path.exists(config_file):
            logger.info(f"配置文件 {config_file} 不存在，创建新文件")
            with open(config_file, 'w', encoding='utf-8') as f:
                json.dump([], f, ensure_ascii=False, indent=4)
        
        # 读取配置文件
        with open(config_file, 'r', encoding='utf-8') as f:
            tasks = json.load(f)
        
        # 检查配置文件格式
        if not isinstance(tasks, list):
            logger.error("配置文件格式错误，应为列表格式")
            return 0
        
        # 遍历所有任务
        for i, task in enumerate(tasks):
            if task.get("Status") == "未使用":
                
                # 获取friend_name和content字段
                friend_name = task.get("friend_name")
                content = task.get("content")
                
                if friend_name and content:
                    logger.info(f"准备发布任务 #{i} 给好友 {friend_name}")
                    # 解析JSON内容
                    try:
                        content_obj = json.loads(content)
                        # 遍历script数组发送消息
                        for script_msg in content_obj.get('script', []):
                            wx.SendMsg(msg=script_msg, who=friend_name)
                            logger.info(f"已向 {friend_name} 发送消息: {script_msg[:30]}...")
                            time.sleep(1)  # 消息间隔
                    except json.JSONDecodeError:
                        # 兼容旧格式直接发送
                        logger.debug(f"使用旧格式发送消息给 {friend_name}")
                        wx.SendMsg(msg=content, who=friend_name)
                        logger.info(f"已向 {friend_name} 发送消息: {content[:30]}...")
                    
                    # 更新状态为已使用
                    tasks[i]["Status"] = "已使用"
                    published_count += 1
                else:
                    logger.warning(f"任务 #{i} 缺少必要字段 friend_name 或 content")
        
        # 将更新后的任务列表写回文件
        with open(config_file, 'w', encoding='utf-8') as f:
            json.dump(tasks, f, ensure_ascii=False, indent=4)
        
        logger.info(f"成功发布 {published_count} 条消息，并更新了状态")
        
    except (FileNotFoundError, json.JSONDecodeError) as e:
        logger.error(f"读取或解析配置文件时出错: {str(e)}")
    except Exception as e:
        logger.error(f"发布消息过程中发生未知错误: {str(e)}", exc_info=True)
    
    return published_count

def start_ai_worker():
    """
    启动AI处理工作线程
    """
    logger.info("开始启动AI处理工作线程")
    
    # 创建线程池
    worker_thread = threading.Thread(target=ai_worker, daemon=True)
    # 启动线程
    worker_thread.start()

    logger.info("AI处理工作线程已启动")
    return worker_thread

if __name__ == "__main__":
    logger.info("=== 微信AI助手程序启动 ===")
    
    # 启动AI处理工作线程
    worker_thread = start_ai_worker()
    
    # 检查并初始化配置文件
    config_file = "config/push_task_config.json"
    if not os.path.exists(config_file):
        logger.info(f"程序启动时创建配置文件 {config_file}")
        with open(config_file, 'w', encoding='utf-8') as f:
            json.dump([], f, ensure_ascii=False, indent=4)
    
    while True:
        try:
            # 巡查微信新消息
            logger.debug("开始巡查微信新消息")
            friend_name = check_messages(timeout=30)  
            
            if friend_name:
                logger.info(f"检测到好友 {friend_name} 的新消息")
                
                # 从微信获取消息并保存到文件
                Page = 3  # 加载微信消息的页数
                logger.debug(f"开始加载 {Page} 页微信消息")
                friend_name, saved_file_path = save_messages_to_file(load_iterations=Page)
                
                # 构造AI提示词与上下文内容
                messages = build_deepseek_messages(saved_file_path)
                
                # 从配置文件获取API密钥，而不是硬编码
                api_key = get_api_key("deepseek")
                
                # 异步处理AI聊天
                handle_ai_chat(friend_name, messages, api_key)
            
            # 发布未使用的消息
            publish_messages()
            
            # 短暂休眠，避免CPU占用过高
            time.sleep(1)
            
        except KeyboardInterrupt:
            logger.info("程序收到终止信号，等待任务队列清空...")
            ai_task_queue.join()    # 等待任务队列清空
            logger.info("所有任务已完成，程序正常退出")
            break
        except Exception as e:
            logger.error(f"主循环出错: {str(e)}", exc_info=True)
            logger.info("5秒后重试...")
            time.sleep(5)  # 出错后等待一段时间再继续













